/**
 * 项目名称（软件名称）：忠旺机械物资管理系统(mms)
 * 研发设计单位：忠旺机械设备制造有限公司机械设计院智能控制设计科设计与研发。
 * 版权所有：忠旺机械设备制造有限公司
 * 注：本项目的一切技术专利，使用规范归解释权由忠旺机械设备制造有限公司所有。
 * 软件版本：Ver 1.0.0
 * 文件路径：com.zhongwang.mms.module.purchase.controller
 * 创建时间：2020年04月11日 16时42分
 **/
package com.zhongwang.mms.module.purchase.service;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.zhongwang.mms.base.BaseService;
import com.zhongwang.mms.common.ImportCallBack;
import com.zhongwang.mms.common.JsonResult;
import com.zhongwang.mms.gen.entity.*;
import com.zhongwang.mms.module.basic.dao.*;
import com.zhongwang.mms.module.basic.model.TProjectModel;
import com.zhongwang.mms.module.basic.service.BoardService;
import com.zhongwang.mms.module.purchase.dao.PurPInventoryDao;
import com.zhongwang.mms.module.purchase.dao.PurChangeDao;
import com.zhongwang.mms.module.purchase.dao.PurTProjectDao;
import com.zhongwang.mms.module.purchase.dao.PurWarInManageDao;
import com.zhongwang.mms.module.purchase.excelListener.PChangeOrderListener;
import com.zhongwang.mms.module.purchase.model.*;
import com.zhongwang.mms.module.system.util.GetDateTimeService;
import com.zhongwang.mms.util.ExportExcelUtils;
import com.zhongwang.mms.util.FileUtils;
import com.zhongwang.mms.util.ShiroUtils;
import com.zhongwang.mms.util.StringUtils;
import lombok.extern.log4j.Log4j2;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.zhongwang.mms.config.timingtask.StatisticalTimingTask.getVWProjectByCode;

/**
 * @ClassName： PurChangeController
 * @Description： 串料控制层
 * @Author： 徐一贺
 * @Date： 2020/4/11 16:42
 * @Version： V1.0
 **/
@Log4j2
@Service
public class PurChangeService extends BaseService {
    @Value("${user.upload.path}")
    private String uploadPath;
    @Autowired
    private PurChangeDao purChangeDao;
    @Autowired
    private PurPInventoryDao purPInventoryDao;
    @Autowired
    private GetDateTimeService getDateTimeService;
    @Autowired
    private PurTProjectDao purTProjectDao;
    @Autowired
    private TDeptDao tDeptDao;
    @Autowired
    private BoardDao boardDao;
    @Autowired
    private BaseService baseService;
    @Autowired
    private TWarehouseInfoDao tWarehouseInfoDao;
    @Autowired
    private TProjectDao tProjectDao;
    @Autowired
    private PurWarInManageDao purWarInManageDao;
    @Autowired
    private BoardService boardService;
    @Autowired
    private TCostDao tCostDao;

    /**
     * @FunctionName: findChangePlanList
     * @Description: 获取串料计划列表
     * @Author: 徐一贺
     * @CreateDate: 2020/4/15 19:39
     * @Phone: 18241927380
     * @Param: [queryModel] 检索参数
     * @Return: [List<ChangeModel>] 串料计划列表
     * @Version: 1.0.0
     */
    public List<ChangeModel> findChangePlanList(ChangeModel queryModel) {
        return purChangeDao.findChangePlanList(queryModel);
    }

    /**
     * @FunctionName: toChange
     * @Description: 生成串料单
     * @Author: 徐一贺
     * @CreateDate: 2020/4/16 10:54
     * @Phone: 18241927380
     * @Param: [param] 前台参数
     * @Return:
     * @Version: 1.0.0
     */
    public boolean toChange(ChangeModel param) {
        try {
            //根据主键获取计划信息
            BReportPlan bReportPlan = purChangeDao.getBReportPlanPrimaryKey(param.getCeoRppId());
            //根据主键获取库存信息
            PInventory ceoUsePInventory = purChangeDao.getInventoryPrimaryKey(param.getCeoNeedItyId());
            PChangeOrder pChangeOrder = purChangeDao.getPChangeOrderByRppId(param.getCeoRppId());
            String oprType = "update";
            if (pChangeOrder == null) {
                oprType = "insert";
                //创建串料信息
                pChangeOrder = new PChangeOrder();
                pChangeOrder.setCeoCode(generateCCOrderCode());
            }
            pChangeOrder.setCeoRppId(bReportPlan.getRppId());
            pChangeOrder.setCeoNeedItyId(ceoUsePInventory.getItyId());
            pChangeOrder.setCeoItyType("p");
            if (ceoUsePInventory.getItyAvaNum() > bReportPlan.getRppNum()) {
                pChangeOrder.setCeoType(2);
            } else {
                pChangeOrder.setCeoType(1);
            }
            pChangeOrder.setCeoAppPersonId(ShiroUtils.getUser().getId());
            pChangeOrder.setCeoAppDate(new Date());
            TProject project = purTProjectDao.findProjectByCode(ceoUsePInventory.getItyProCode());

            pChangeOrder.setCeoNeedStatus(param.getCeoNeedStatus());

            pChangeOrder.setCeoNeedProCode(ceoUsePInventory.getItyProCode());
            pChangeOrder.setCeoNeedProName(ceoUsePInventory.getItyProName());
            pChangeOrder.setCeoNeedMatName(ceoUsePInventory.getItyMatDesc());

            pChangeOrder.setCeoNeedNum(ceoUsePInventory.getItyAvaNum());
            pChangeOrder.setCeoNeedWeight(bReportPlan.getRppNum());
            pChangeOrder.setCeoAppyStatus(1);
            if (oprType.equals("insert")) {
                purChangeDao.insertSelective(pChangeOrder);
            } else {
                purChangeDao.uppdateSelective(pChangeOrder);
            }
            logService.saveLog("【外购件】创建串料单", "串料单号：" + pChangeOrder.getCeoCode());
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
        }
        return false;
    }

    /**
     * @FunctionName: saveChangeOrder
     * @Description: 保存串料标记
     * @Author: 徐一贺
     * @CreateDate: 2020/4/20 11:17
     * @Phone: 18241927380
     * @Param: [param] 参数
     * @Return: 结果
     * @Version: 1.0.0
     */
    @Transactional(rollbackFor = Exception.class)
    public JsonResult saveChangeOrder(PChangeOrder param) {
        JsonResult jsonResult = new JsonResult();
        try {
            if (param.getCeoNeedNum().doubleValue() <= 0) {
                jsonResult.setType(JsonResult.ResultType.ERROR);
                jsonResult.setMsg("需求数量不能小于等于0！");
                return jsonResult;
            }
            //根据主键获取库存信息
            PInventory ceoUsePInventory = purChangeDao.getInventoryPrimaryKey(param.getCeoUseItyId());
//            if (tCostDao.getTCostByCosProCode(param.getCeoNeedProCode()) != null) {
//                jsonResult.setType(JsonResult.ResultType.ERROR);
//                jsonResult.setMsg("需求项目编号不可以是成本中心项目！");
//                return jsonResult;
//            }
            if (param.getCeoNeedProCode().toUpperCase().trim().equals(ceoUsePInventory.getItyProCode().toUpperCase().trim())) {
                jsonResult.setType(JsonResult.ResultType.ERROR);
                jsonResult.setMsg("需求项目编号不可与挪用项目编号相同！");
                return jsonResult;
            }
            if (param.getCeoId() == null || param.getCeoId() == 0) {
                if (ceoUsePInventory.getItyAvaNum().doubleValue() <= 0 || ceoUsePInventory.getItyNum().doubleValue() <= 0) {
                    jsonResult.setType(JsonResult.ResultType.ERROR);
                    jsonResult.setMsg("挪用物料可用数量不足！");
                    return jsonResult;
                }
                if (ceoUsePInventory.getItyNum().doubleValue() < param.getCeoNeedNum().doubleValue()) {
                    jsonResult.setType(JsonResult.ResultType.ERROR);
                    jsonResult.setMsg("挪用物料可用数量不足！");
                    return jsonResult;
                }
                if (ceoUsePInventory.getItyAvaNum().doubleValue() < param.getCeoNeedNum().doubleValue()) {
                    jsonResult.setType(JsonResult.ResultType.ERROR);
                    jsonResult.setMsg("挪用物料可用数量不足！");
                    return jsonResult;
                }
                param.setCeoAppDate(new Date());
                param.setCeoItyType("p");
                param.setCeoAppPersonId(ShiroUtils.getUser().getId());
                param.setCeoUseMatCode(ceoUsePInventory.getItySapCode());
                param.setCeoAppyStatus(1);
                if (ceoUsePInventory.getItyAvaNum() > param.getCeoNeedNum()) {
                    param.setCeoType(2);
                } else {
                    param.setCeoType(1);
                }
                param.setCeoUseMatName(StringUtils.replaceNbspToSpace(param.getCeoUseMatName()));
                param.setCeoUseProName(StringUtils.replaceNbspToSpace(param.getCeoUseProName()));
                param.setCeoNeedMatName(StringUtils.replaceNbspToSpace(param.getCeoNeedMatName()));
                param.setCeoNeedProName(StringUtils.replaceNbspToSpace(param.getCeoNeedProName()));
                //更改库存可用数量
                ceoUsePInventory.setItyAvaNum(ceoUsePInventory.getItyAvaNum() - param.getCeoNeedNum());
                purPInventoryDao.updateItyAvaNumByPrimary(ceoUsePInventory);
                param.setCeoCode(generateCCOrderCode());
                purChangeDao.insertSelective(param);
                logService.saveLog("【外购件】保存串料标记", "保存的标记的库存物料描述：" + ceoUsePInventory.getItyMatDesc());
                jsonResult.setType(JsonResult.ResultType.SUCCESS);
                jsonResult.setMsg("创建串料申请成功！");
                return jsonResult;
            } else {
                PChangeOrder pChangeOrder = purChangeDao.getPChangeOrderByPrimaryKey(param.getCeoId());
                if (pChangeOrder.getCeoNeedNum().doubleValue() + ceoUsePInventory.getItyAvaNum().doubleValue() <= 0) {
                    jsonResult.setType(JsonResult.ResultType.ERROR);
                    jsonResult.setMsg("挪用物料可用数量不足！");
                    return jsonResult;
                }
                if (pChangeOrder.getCeoNeedNum().doubleValue() + ceoUsePInventory.getItyNum().doubleValue() <= 0) {
                    jsonResult.setType(JsonResult.ResultType.ERROR);
                    jsonResult.setMsg("挪用物料可用数量不足！");
                    return jsonResult;
                }
                if (pChangeOrder.getCeoNeedNum().doubleValue() + ceoUsePInventory.getItyAvaNum().doubleValue() < param.getCeoNeedNum()) {
                    jsonResult.setType(JsonResult.ResultType.ERROR);
                    jsonResult.setMsg("挪用物料可用数量不足！");
                    return jsonResult;
                }
                if (pChangeOrder.getCeoNeedNum().doubleValue() + ceoUsePInventory.getItyNum().doubleValue() < param.getCeoNeedNum().doubleValue()) {
                    jsonResult.setType(JsonResult.ResultType.ERROR);
                    jsonResult.setMsg("挪用物料可用数量不足！");
                    return jsonResult;
                }
                param.setCeoAppDate(new Date());
                param.setCeoItyType("p");
                param.setCeoAppPersonId(ShiroUtils.getUser().getId());
                param.setCeoUseMatCode(ceoUsePInventory.getItySapCode());
                param.setCeoAppyStatus(1);
                if (ceoUsePInventory.getItyAvaNum() > param.getCeoNeedNum()) {
                    param.setCeoType(2);
                } else {
                    param.setCeoType(1);
                }
                param.setCeoUseMatName(StringUtils.replaceNbspToSpace(param.getCeoUseMatName()));
                param.setCeoUseProName(StringUtils.replaceNbspToSpace(param.getCeoUseProName()));
                param.setCeoNeedMatName(StringUtils.replaceNbspToSpace(param.getCeoNeedMatName()));
                param.setCeoNeedProName(StringUtils.replaceNbspToSpace(param.getCeoNeedProName()));
                //获取原串料数据
                PChangeOrderModel source = purChangeDao.getPChangeOrderByPrimaryKey(param.getCeoId());
                ceoUsePInventory.setItyAvaNum(source.getCeoNeedNum() + ceoUsePInventory.getItyAvaNum() - param.getCeoNeedNum());
                purPInventoryDao.updateItyAvaNumByPrimary(ceoUsePInventory);
                purChangeDao.uppdateSelective(param);
                logService.saveLog("【外购件】保存串料标记", "保存的标记的库存物料描述：" + ceoUsePInventory.getItyMatDesc());
                jsonResult.setType(JsonResult.ResultType.SUCCESS);
                jsonResult.setMsg("创建串料申请成功！");
                return jsonResult;
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            jsonResult.setType(JsonResult.ResultType.ERROR);
            jsonResult.setMsg("创建串料申请失败！");
            return jsonResult;
        }
    }


    /**
     * @FunctionName: generateCCOrderCode
     * @Description: 获取串料单编码
     * @Author: 徐一贺
     * @CreateDate: 2020/4/16 13:06
     * @Phone: 18241927380
     * @Param:
     * @Return:
     * @Version:
     */
    private String generateCCOrderCode() {
        String newGeneratePRKOrderCode = "";
        //获取最后编码
        String lastCCOrderCode = purChangeDao.findLastCCOrderCode();
        if (null == lastCCOrderCode) {
            lastCCOrderCode = "";
        }
        //获取当前时间简码
        String datetimeCode = new SimpleDateFormat("yyMMdd").format(new Date());
        Integer sn = 0;
        if (lastCCOrderCode.length() > 0) {
            //获取外购件库最新最后的入库单号
            sn = Integer.parseInt(lastCCOrderCode.substring(9));
        }

        if (lastCCOrderCode.length() == 0) {
            newGeneratePRKOrderCode = "CC" + new SimpleDateFormat("yyMMdd").format(new Date()) + "000001";
        } else if (!lastCCOrderCode.substring(2, 8).equals(datetimeCode)) {
            newGeneratePRKOrderCode = "CC" + new SimpleDateFormat("yyMMdd").format(new Date()) + "000001";
        } else {
            newGeneratePRKOrderCode = "CC" + new SimpleDateFormat("yyMMdd").format(new Date()) + String.format("%06d", (sn + 1));
        }
        return newGeneratePRKOrderCode;
    }


    /**
     * @FunctionName: getPInventory
     * @Description: 根据需求的库存信息主键查找库存信息
     * @Author: 徐一贺
     * @CreateDate: 2020/4/18 10:09
     * @Phone: 18241927380
     * @Param: [ceoUseItyId] 需求的库存信息主键
     * @Return: [pInventory] 查找到了库存信息
     * @Version: 1.0.0
     */
    public PChangeOrder getPInventory(Integer ceoUseItyId) {
//        var proStatusText=["","制作中","待制作","暂缓","完成"];
        PInventory pInventory = purChangeDao.findInventoryByParam(ceoUseItyId);
        TProject tProject = purChangeDao.getTProjectByProCode(pInventory.getItyProCode());
        PChangeOrder pChangeOrder = new PChangeOrder();
        pChangeOrder.setCeoUseItyId(pInventory.getItyId());
        if (null != tProject) {
            if (tProject.getProProductionStatus() == 1) {
                pChangeOrder.setCeoUseStatus("执行中");
            }
            if (tProject.getProProductionStatus() == 2) {
                pChangeOrder.setCeoUseStatus("未开始");
            }
            if (tProject.getProProductionStatus() == 3) {
                pChangeOrder.setCeoUseStatus("暂缓");
            }
            if (tProject.getProProductionStatus() == 4) {
                pChangeOrder.setCeoUseStatus("已完成");
            }
            if (tProject.getProProductionStatus() == 5) {
                pChangeOrder.setCeoUseStatus("取消");
            }
            if (tProject.getProProductionStatus() == -1) {
                pChangeOrder.setCeoUseStatus("无状态");
            }
        }
        pChangeOrder.setCeoUseProCode(pInventory.getItyProCode());
        pChangeOrder.setCeoUseProName(pInventory.getItyProName());
        pChangeOrder.setCeoUseMatName(pInventory.getItyMatDesc());
        pChangeOrder.setCeoUseMatCode(pInventory.getItySapCode());

        pChangeOrder.setCeoUseNum(pInventory.getItyAvaNum());
        pChangeOrder.setCeoUseUnit(pInventory.getItyNumUnit());
        pChangeOrder.setCeoNeedUnit(pInventory.getItyNumUnit());
        pChangeOrder.setCeoUseWhiId(pInventory.getItyWhiId());
        pChangeOrder.setCeoUsePosition(pInventory.getItyPosition());


        return pChangeOrder;
    }

    /**
     * @FunctionName: findVWProjectByLikeCode
     * @Description: 根据项目号模糊查询获取看板系统项目信息与本地系统项目状态列表
     * @Author: 徐一贺
     * @CreateDate: 2020/4/18 12:52
     * @Phone: 18241927380
     * @Param: [param] 包含项目号实体类
     * @Return: [List<VWProject>] 项目看板系统列表信息
     * @Version: 1.0.0
     */
    public List<VWProject> findVWProjectByLikeCode(VWProject param) {
        return purChangeDao.findVWProjectByLikeCode(param);
    }

    /**
     * @FunctionName: codeExist
     * @Description: bootstrapValidate验证：验证项目号是否存在
     * @JavaScriptDemo： notEmpty: {message: '请输入需求项目编号'},
     * threshold: 6, //有6字符以上才发送ajax请求，（input中输入一个字符，插件会向服务器发送一次，设置限制，6字符以上才开始）
     * remote: {//ajax验证。server result:{"valid",true or false} 向服务发送当前input name值，获得一个json数据。例表示正确：{"valid",true}
     * url: 'purchase/change/codeExist',//验证地址
     * message: '用户已存在',//提示消息
     * delay: 100,//每输入一个字符，就发ajax请求，服务器压力还是太大，设置2秒发送一次ajax（默认输入一个字符，提交一次，服务器压力太大）
     * type: 'POST'//请求方式
     * /**自定义提交数据，默认值提交当前input value
     * *  data: function(validator) {
     * return {
     * password: $('[name="passwordNameAttributeInYourForm"]').val(),
     * whatever: $('[name="whateverNameAttributeInYourForm"]').val()
     * };
     * }
     * @Author: 徐一贺
     * @CreateDate: 2020/4/18 13:24
     * @Phone: 18241927380
     * @Param: [param] 项目号
     * @Return: java.lang.Boolean
     * @Version: 1.0.0
     */
    public boolean codeExist(VWProject param) {
        param = getVWProjectByCode(param.getCeoNeedProCode());
        if (null != param) {
            return true;
        }
        return false;
    }

    /**
     * @FunctionName: proInfoExist
     * @Description: 根据项目号查询本系统项目是否存在
     * @Author: 徐一贺
     * @CreateDate: 2020/4/20 13:31
     * @Phone: 18241927380
     * @Param: [param] 项目号
     * @Return: [Boolean] 返回结果
     * @Version: 1.0.0
     */
    public Boolean proInfoExist(VWProject param) {
        TProject tProject = purChangeDao.getTProjectByProCode(param.getCode());
        return tProject != null;
    }

    /**
     * @FunctionName: findChangeOrderListByQuery
     * @Description: 根据条件号查询串料标记执行表列表数据
     * @Author: 徐一贺
     * @CreateDate: 2020/4/20 14:47
     * @Phone: 18241927380
     * @Param: [queryModel] 查询条件
     * @Return: [List<PChangeOrderModel>] 串料单标记列表
     * @Version: 1.0.0
     */
    public List<ChangeModel> findChangeOrderListByQuery(ChangeOrderQueryModel queryModel) {
        if (queryModel.getEndDate() != null) {
            Calendar cal = Calendar.getInstance();
            cal.setTime(queryModel.getEndDate());
            cal.add(Calendar.DAY_OF_YEAR, 1);
            queryModel.setEndDate(cal.getTime());
        }
        if (queryModel.getEndRemoveDate() != null) {
            Calendar cal = Calendar.getInstance();
            cal.setTime(queryModel.getEndRemoveDate());
            cal.add(Calendar.DAY_OF_YEAR, 1);
            queryModel.setEndRemoveDate(cal.getTime());
        }
        if (queryModel.getEndSubmitDate() != null) {
            Calendar cal = Calendar.getInstance();
            cal.setTime(queryModel.getEndSubmitDate());
            cal.add(Calendar.DAY_OF_YEAR, 1);
            queryModel.setEndSubmitDate(cal.getTime());
        }
        return purChangeDao.findChangeOrderListByQuery(queryModel);
    }

    /**
     * @FunctionName: findChangeOrderExecListByQuery
     * @Description: 获取串料执行列表
     * @Author: 徐一贺
     * @CreateDate: 2020/4/21 19:43
     * @Phone: 18241927380
     * @Param: [queryModel] 检索参数
     * @Return: [List<ChangeModel>] 串料执行列表
     * @Version: 1.0.0
     */
    public List<ChangeModel> findChangeOrderExecListByQuery(ChangeOrderQueryModel queryModel) {
        if (queryModel.getEndDate() != null) {
            Calendar cal = Calendar.getInstance();
            cal.setTime(queryModel.getEndDate());
            cal.add(Calendar.DAY_OF_YEAR, 1);
            queryModel.setEndDate(cal.getTime());
        }
        if (queryModel.getExecEndDate() != null) {
            Calendar cal = Calendar.getInstance();
            cal.setTime(queryModel.getExecEndDate());
            cal.add(Calendar.DAY_OF_YEAR, 1);
            queryModel.setExecEndDate(cal.getTime());
        }
        if (queryModel.getEndSubmitDate() != null) {
            Calendar cal = Calendar.getInstance();
            cal.setTime(queryModel.getEndSubmitDate());
            cal.add(Calendar.DAY_OF_YEAR, 1);
            queryModel.setEndSubmitDate(cal.getTime());
        }
        List<ChangeModel> list = new ArrayList<>();
        try {
            list =   purChangeDao.findChangeOrderExecListByQuery(queryModel);
        }catch (Exception e){
            log.error(e.getMessage());
        }
        return list;
    }

    /**
     * @FunctionName: findDeptList
     * @Description: 获取单位列表
     * @Author: 徐一贺
     * @CreateDate: 2020/4/21 10:13
     * @Phone: 18241927380
     * @Param:
     * @Return: [List<TDept>] 单位列表
     * @Version: 1.0.0
     */
    public List<TDept> findDeptList() {
        return tDeptDao.selectByExample(null);
    }

    /**
     * @FunctionName: submitAppy
     * @Description: 提交
     * @Author: 徐一贺
     * @CreateDate: 2020/4/21 12:39
     * @Phone: 18241927380
     * @Param: [param]
     * @Return: com.zhongwang.mms.common.JsonResult
     * @Version: 1.0.0
     */
    public boolean submitAppy(PChangeOrderModel param) {
        try {
            Date currentDate = new Date();
            List<PChangeOrderModel> submitAppyList = purChangeDao.findPChangeOrderByCeoId(param.getCeoIds());
            for (PChangeOrderModel pChangeOrderModel : submitAppyList) {
                if (pChangeOrderModel.getCeoAppyStatus().equals(1) || pChangeOrderModel.getCeoAppyStatus().equals(4)) {
                    param.setCeoAppyStatus(2);
                    param.setCeoSubmitDate(currentDate);
                    purChangeDao.updatePChangeOrderCeoAppyStatusByCeoId(param);
                    logService.saveLog("【外购件】提交串料申请", "提交的串料单编号：" + pChangeOrderModel.getCeoCode());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return false;
        }
        return true;
    }

    /**
     * @FunctionName: execApply
     * @Description: 执行
     * @Author: 徐一贺
     * @CreateDate: 2020/4/21 20:12
     * @Phone: 18241927380
     * @Param: [param] 执行参数
     * @Return: [boolean] 执行结果
     * @Version: 1.0.0
     *
     * @Update: wsg
     * @Description: 由于原代码手动抛异常和try catch自己吞异常的原因，事务无法回滚导致脏数据
     * @UpdateDate: 2023/10/14
     */
    @Transactional(rollbackFor = Exception.class)
    public String execApply(PChangeOrderModel param) {
        String msg = "";  // 返回提示信息
        String errorReason; // 校验原因
        PChangeOrderModel ityToPro;
        PInventory inventory;

        List<PChangeOrderModel> pChangeOrderModelList = purChangeDao.findPChangeOrderByCeoId(param.getCeoIds());
        for (int i = 0; i < pChangeOrderModelList.size(); i++){
            ityToPro = pChangeOrderModelList.get(i);
            inventory = purPInventoryDao.selectByPrimaryKey(ityToPro.getCeoUseItyId());
            // 校验是否满足库存划项目执行条件
            errorReason = checkValidate(ityToPro, inventory);
            if (errorReason.length() == 0) {
                //满足条件 执行操作
                checkMethod(ityToPro, inventory);
            } else {
                msg = msg + errorReason;
                continue;
            }
        }
        return msg.length() > 0 ? msg + "<br> 以上数据库存划项目执行失败！" : "库存划项目执行成功！";
    }

    /**
     * 库存划项目执行
     *
     * @param pChangeOrderModel        标记记录
     * @param ceoUsePInventory 原料在库
     */
    private void checkMethod(PChangeOrderModel pChangeOrderModel, PInventory ceoUsePInventory){
        //如果是串料（全部）
        if (pChangeOrderModel.getCeoType().equals(1)) {
            Integer beforeChangeFlag = 0;
            //插入串过来库存的数据
            if (ceoUsePInventory.getItyAncestorsProCode() == null) {
                ceoUsePInventory.setItyAncestorsProCode(ceoUsePInventory.getItyProCode());
            }
            if (ceoUsePInventory.getItyAncestorsTrackCode() == null) {
                ceoUsePInventory.setItyAncestorsTrackCode(ceoUsePInventory.getItyTrackCode());
            }
            if (ceoUsePInventory.getItyAncestorsLevel() == null) {
                ceoUsePInventory.setItyAncestorsLevel(1);
            } else {
                ceoUsePInventory.setItyAncestorsLevel(ceoUsePInventory.getItyAncestorsLevel() + 1);
            }
            if (ceoUsePInventory.getItyAncestorsIdentity() == null) {
                ceoUsePInventory.setItyAncestorsIdentity("leaf");
            } else {
                PInventory changeItyAncestorsIdentityModel = new PInventory();
                changeItyAncestorsIdentityModel.setItyId(ceoUsePInventory.getItyId());
                changeItyAncestorsIdentityModel.setItyAncestorsIdentity("trunk");
                purPInventoryDao.updateByPrimaryKeySelective(changeItyAncestorsIdentityModel);
                ceoUsePInventory.setItyAncestorsIdentity("leaf");
            }
            if (ceoUsePInventory.getItyAncestorsNum() == null) {
                ceoUsePInventory.setItyAncestorsNum(ceoUsePInventory.getItyNum());
            }
            ceoUsePInventory.setItyProCode(pChangeOrderModel.getCeoNeedProCode());
            ceoUsePInventory.setItyProName(pChangeOrderModel.getCeoNeedProName());
            ceoUsePInventory.setItyNum(pChangeOrderModel.getCeoNeedNum());
            ceoUsePInventory.setItyAvaNum(pChangeOrderModel.getCeoNeedNum());
            //2020年8月19日16:32:01 根据盖世奇转述，成本中心项目为库存在库
            if (tCostDao.getTCostByCosProCode(pChangeOrderModel.getCeoNeedProCode()) != null) {
                ceoUsePInventory.setItyStockType(1);
            } else {
                ceoUsePInventory.setItyStockType(2);
            }
            beforeChangeFlag = ceoUsePInventory.getItyChangeFlag();
            ceoUsePInventory.setItyChangeFlag(1);
            purPInventoryDao.insert(ceoUsePInventory);
            //反写使用的库存信息到串料数据中,等待提报计划指定。
            pChangeOrderModel.setCeoNeedItyId(ceoUsePInventory.getItyId());
            pChangeOrderModel.setCeoAppyStatus(3);
            pChangeOrderModel.setCeoStatus(1);
            pChangeOrderModel.setCeoAuditorId(ShiroUtils.getUser().getId());
            pChangeOrderModel.setCeoAuditDate(new Date());
            purChangeDao.uppdateSelective(pChangeOrderModel);
            pChangeOrderModel.setCeoPrice(ceoUsePInventory.getItyPrice());
            purChangeDao.updateCeoPrice(pChangeOrderModel);
            //获取原库存数据并更改其值为,库存数量为库存来减去可用数量，可用数量清零。
            ceoUsePInventory = purChangeDao.getInventoryPrimaryKey(pChangeOrderModel.getCeoUseItyId());
            ceoUsePInventory.setItyNum(ceoUsePInventory.getItyNum() - pChangeOrderModel.getCeoNeedNum());
            purPInventoryDao.updatePInventoryNumPrimaryKey(ceoUsePInventory);
            if (beforeChangeFlag == null || beforeChangeFlag.equals(0) || beforeChangeFlag.equals(2)) {
                ceoUsePInventory.setItyChangeFlag(2);
            } else if (beforeChangeFlag == 1) {
                ceoUsePInventory.setItyChangeFlag(3);
            } else if (beforeChangeFlag == 3) {
                ceoUsePInventory.setItyChangeFlag(3);
            }
            //更改串料标记
            purPInventoryDao.updateItyChangeFlagByPrimaryKey(ceoUsePInventory);
        } else if (pChangeOrderModel.getCeoType().equals(2)) {
            //插入串过来库存的数据
            Integer beforeChangeFlag = 0;
            if (ceoUsePInventory.getItyAncestorsProCode() == null) {
                ceoUsePInventory.setItyAncestorsProCode(ceoUsePInventory.getItyProCode());
            }
            if (ceoUsePInventory.getItyAncestorsTrackCode() == null) {
                ceoUsePInventory.setItyAncestorsTrackCode(ceoUsePInventory.getItyTrackCode());
            }
            if (ceoUsePInventory.getItyAncestorsLevel() == null) {
                ceoUsePInventory.setItyAncestorsLevel(1);
            } else {
                ceoUsePInventory.setItyAncestorsLevel(ceoUsePInventory.getItyAncestorsLevel() + 1);
            }
            if (ceoUsePInventory.getItyAncestorsIdentity() == null) {
                ceoUsePInventory.setItyAncestorsIdentity("leaf");
            } else {
                PInventory changeItyAncestorsIdentityModel = new PInventory();
                changeItyAncestorsIdentityModel.setItyId(ceoUsePInventory.getItyId());
                changeItyAncestorsIdentityModel.setItyAncestorsIdentity("trunk");
                purPInventoryDao.updateByPrimaryKeySelective(changeItyAncestorsIdentityModel);
                ceoUsePInventory.setItyAncestorsIdentity("leaf");
            }
            if (ceoUsePInventory.getItyAncestorsNum() == null) {
                ceoUsePInventory.setItyAncestorsNum(ceoUsePInventory.getItyNum());
            }
            ceoUsePInventory.setItyProCode(pChangeOrderModel.getCeoNeedProCode());
            ceoUsePInventory.setItyProName(pChangeOrderModel.getCeoNeedProName());
            ceoUsePInventory.setItyNum(pChangeOrderModel.getCeoNeedNum());
            ceoUsePInventory.setItyAvaNum(pChangeOrderModel.getCeoNeedNum());
            beforeChangeFlag = ceoUsePInventory.getItyChangeFlag();
            if (tCostDao.getTCostByCosProCode(pChangeOrderModel.getCeoNeedProCode()) != null) {
                ceoUsePInventory.setItyStockType(1);
            } else {
                ceoUsePInventory.setItyStockType(2);
            }
            ceoUsePInventory.setItyChangeFlag(1);
            purPInventoryDao.insert(ceoUsePInventory);
            //反写使用的库存信息到串料数据中,等待提报计划指定。
            pChangeOrderModel.setCeoNeedItyId(ceoUsePInventory.getItyId());
            pChangeOrderModel.setCeoAppyStatus(3);
            pChangeOrderModel.setCeoStatus(1);
            pChangeOrderModel.setCeoAuditorId(ShiroUtils.getUser().getId());
            pChangeOrderModel.setCeoAuditDate(new Date());
            purChangeDao.uppdateSelective(pChangeOrderModel);
            pChangeOrderModel.setCeoPrice(ceoUsePInventory.getItyPrice());
            purChangeDao.updateCeoPrice(pChangeOrderModel);
            //获取原库存数据并更改其值为,库存数量为库存来减去可用数量，可用数量清零。
            ceoUsePInventory = purChangeDao.getInventoryPrimaryKey(pChangeOrderModel.getCeoUseItyId());
            ceoUsePInventory.setItyNum(ceoUsePInventory.getItyNum() - pChangeOrderModel.getCeoNeedNum());
            purPInventoryDao.updatePInventoryNumPrimaryKey(ceoUsePInventory);
            if (beforeChangeFlag == null || beforeChangeFlag.equals(0) || beforeChangeFlag.equals(2)) {
                ceoUsePInventory.setItyChangeFlag(2);
            } else if (beforeChangeFlag == 1) {
                ceoUsePInventory.setItyChangeFlag(3);
            } else if (beforeChangeFlag == 3) {
                ceoUsePInventory.setItyChangeFlag(3);
            }
            //更改串料标记
            purPInventoryDao.updateItyChangeFlagByPrimaryKey(ceoUsePInventory);
        }
        logService.saveLog("【外购件】执行串料申请", "执行的串料单编号：" + pChangeOrderModel.getCeoCode());
    }

    /**
     * 校验是否满足库存划项目执行条件
     *
     * @param inventoryProjectMark 库存划项目记录
     * @param inventory            原料在库
     * @return
     */
    private String checkValidate(PChangeOrderModel inventoryProjectMark, PInventory inventory){
        String errorReason = "";
        // 提示信息：项目号 项目名称 标记重量 失败原因
        if (inventoryProjectMark.getCeoAppyStatus() == 3) {
            errorReason = errorReason + "<br>单据编号为：" + inventoryProjectMark.getCeoCode() + "  的串料申请，已经被执行";
        }
        // 判断库存在库量是否充足
        double a = inventory.getItyNum();
        double c = inventoryProjectMark.getCeoNeedNum();
        if (a < c) {
            errorReason = errorReason + "<br>" + inventory.getItyProCode() + "  " + inventory.getItyProName() + "  标记量 " + inventoryProjectMark.getCeoNeedNum() + "  库存在库量不足";
        }
        return errorReason;
    }

    /**
     * @FunctionName: revokeAppy
     * @Description: 撤销
     * @Author: 徐一贺
     * @CreateDate: 2020/4/22 9:20
     * @Phone: 18241927380
     * @Param: [param] 撤销参数
     * @Return: [boolean] 侧小结果
     * @Version: 1.0.0
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean revokeAppy(PChangeOrderModel param) {
        try {
            List<PChangeOrderModel> pChangeOrderModelList = purChangeDao.findPChangeOrderByCeoId(param.getCeoIds());
            //检测所有申请是否已经出库或被串料，如何验证出库，即串料之后的新库存数据可用数量或者库存数量小于串料数量则不可撤销
            for (PChangeOrder pchangeOrder : pChangeOrderModelList) {
                //如果已出库则无法撤销
                if (pchangeOrder.getCeoAppyStatus().equals(5)) {
                    return false;
                }
                //如果已撤销则无法撤销
                if (pchangeOrder.getCeoAppyStatus().equals(4)) {
                    return false;
                }
                //获取因串料新生成的数据
                PInventory ceoNeedPInventory = purChangeDao.getInventoryPrimaryKey(pchangeOrder.getCeoNeedItyId());
                //如果是非成本中心项目
                if (purChangeDao.getTCostByCode(ceoNeedPInventory.getItyProCode()) == null) {
                    //如果被执行项目划库存则不可撤销
                    if (ceoNeedPInventory.getItyStockType().equals(1)) {
                        return false;
                    }
                }
                //如果发现因出库、标记造成的库存数量或可用数量无法撤销则返回假
                if (ceoNeedPInventory.getItyNum() < pchangeOrder.getCeoNeedNum() ||
                        ceoNeedPInventory.getItyAvaNum() < pchangeOrder.getCeoNeedNum()) {
                    return false;
                }
            }
            //更改库存
            //首先获取串料实体类
            for (int i = 0; i < pChangeOrderModelList.size(); i++) {
                PChangeOrderModel pChangeOrderModel = pChangeOrderModelList.get(i);
                //如果是串料（全部）
                if (pChangeOrderModel.getCeoType().equals(1)) {
                    //获取串料生成的库存，清零0库存
                    PInventory ceoNeedPInventory = purChangeDao.getInventoryPrimaryKey(pChangeOrderModel.getCeoNeedItyId());
                    ceoNeedPInventory.setItyNum(0d);
                    ceoNeedPInventory.setItyAvaNum(0d);
                    purPInventoryDao.updateNumByPrimaryKey(ceoNeedPInventory);
                    ceoNeedPInventory.setItyChangeFlag(0);
                    purPInventoryDao.updateItyChangeFlagByPrimaryKey(ceoNeedPInventory);
                    //获取被串料的库存，回写增加被串料的数量
                    PInventory ceoUsePInventory = purChangeDao.getInventoryPrimaryKey(pChangeOrderModel.getCeoUseItyId());
                    ceoUsePInventory.setItyNum(ceoUsePInventory.getItyNum() + pChangeOrderModel.getCeoNeedNum());
                    purPInventoryDao.updateNumByPrimaryKey(ceoUsePInventory);
                    //获取被执行过的串料次数
                    Integer changeCount = purChangeDao.getChangeCountByCeoUseItyId(pChangeOrderModel.getCeoUseItyId());
                    if (ceoUsePInventory.getItyChangeFlag() == 3 && changeCount == 0) {
                        ceoUsePInventory.setItyChangeFlag(1);
                        purPInventoryDao.updateItyChangeFlagByPrimaryKey(ceoUsePInventory);
                    } else if (ceoUsePInventory.getItyChangeFlag() == 3 && changeCount > 0) {
                        ceoUsePInventory.setItyChangeFlag(3);
                        purPInventoryDao.updateItyChangeFlagByPrimaryKey(ceoUsePInventory);
                    } else if (ceoUsePInventory.getItyChangeFlag() == 2 && changeCount > 0) {
                        ceoUsePInventory.setItyChangeFlag(2);
                        purPInventoryDao.updateItyChangeFlagByPrimaryKey(ceoUsePInventory);
                    } else if (ceoUsePInventory.getItyChangeFlag() == 2 && changeCount == 0) {
                        ceoUsePInventory.setItyChangeFlag(0);
                        purPInventoryDao.updateItyChangeFlagByPrimaryKey(ceoUsePInventory);
                    }
                    //撤销提报计划指定状态
                    if (pChangeOrderModel.getCeoRppId() != null) {
                        BReportPlan bReportPlan = purChangeDao.getBReportPlanPrimaryKey(pChangeOrderModel.getCeoRppId());
                        if (bReportPlan != null) {
                            bReportPlan.setRppIsFlag(0);
                            purChangeDao.updateBReportPlanRppIsFlagPrimaryKey(bReportPlan);
                        }
                    }
                    //作废此串料单：清空标记计划ID为0，申请状态为作废。
                    PChangeOrderModel changeModel = new PChangeOrderModel();
                    changeModel.setCeoId(pChangeOrderModel.getCeoId());
                    changeModel.setCeoRppId(null);
                    changeModel.setCeoAppyStatus(2);
                    changeModel.setCeoAuditorId(null);
                    changeModel.setCeoAuditDate(null);
                    changeModel.setCeoNeedItyId(null);
                    purChangeDao.uppdateReject(changeModel);
                } else if (pChangeOrderModel.getCeoType().equals(2)) {
                    //获取串料生成的库存，清零0库存
                    PInventory ceoNeedPInventory = purChangeDao.getInventoryPrimaryKey(pChangeOrderModel.getCeoNeedItyId());
                    ceoNeedPInventory.setItyNum(0d);
                    ceoNeedPInventory.setItyAvaNum(0d);
                    purPInventoryDao.updateNumByPrimaryKey(ceoNeedPInventory);
                    ceoNeedPInventory.setItyChangeFlag(0);
                    purPInventoryDao.updateItyChangeFlagByPrimaryKey(ceoNeedPInventory);
                    //获取被串料的库存，回写增加被串料的数量
                    PInventory ceoUsePInventory = purChangeDao.getInventoryPrimaryKey(pChangeOrderModel.getCeoUseItyId());
                    ceoUsePInventory.setItyNum(ceoUsePInventory.getItyNum() + pChangeOrderModel.getCeoNeedNum());
                    purPInventoryDao.updateNumByPrimaryKey(ceoUsePInventory);
                    //撤销提报计划指定状态
                    if (pChangeOrderModel.getCeoRppId() != null) {
                        BReportPlan bReportPlan = purChangeDao.getBReportPlanPrimaryKey(pChangeOrderModel.getCeoRppId());
                        if (bReportPlan != null) {
                            bReportPlan.setRppIsFlag(0);
                            purChangeDao.updateBReportPlanRppIsFlagPrimaryKey(bReportPlan);
                        }
                    }
                    //如果被制定计划,则清除指定计划的标记状态为0
                    //作废此串料单：清空标记计划ID为0，申请状态为作废。
                    PChangeOrderModel changeModel = new PChangeOrderModel();
                    changeModel.setCeoId(pChangeOrderModel.getCeoId());
                    changeModel.setCeoRppId(null);
                    changeModel.setCeoAppyStatus(2);
                    changeModel.setCeoAuditorId(null);
                    changeModel.setCeoAuditDate(null);
                    changeModel.setCeoNeedItyId(null);
                    purChangeDao.uppdateReject(changeModel);
                    //获取被执行过的串料次数
                    Integer changeCount = purChangeDao.getChangeCountByCeoUseItyId(pChangeOrderModel.getCeoUseItyId());
                    if (ceoUsePInventory.getItyChangeFlag() == 3 && changeCount == 0) {
                        ceoUsePInventory.setItyChangeFlag(1);
                        purPInventoryDao.updateItyChangeFlagByPrimaryKey(ceoUsePInventory);
                    } else if (ceoUsePInventory.getItyChangeFlag() == 3 && changeCount > 0) {
                        ceoUsePInventory.setItyChangeFlag(3);
                        purPInventoryDao.updateItyChangeFlagByPrimaryKey(ceoUsePInventory);
                    } else if (ceoUsePInventory.getItyChangeFlag() == 2 && changeCount > 0) {
                        ceoUsePInventory.setItyChangeFlag(2);
                        purPInventoryDao.updateItyChangeFlagByPrimaryKey(ceoUsePInventory);
                    } else if (ceoUsePInventory.getItyChangeFlag() == 2 && changeCount == 0) {
                        ceoUsePInventory.setItyChangeFlag(0);
                        purPInventoryDao.updateItyChangeFlagByPrimaryKey(ceoUsePInventory);
                    }
                }
                logService.saveLog("【外购件】撤销串料申请", "撤销的串料单编号：" + pChangeOrderModel.getCeoCode());
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return false;
        }
        return true;
    }

    /**
     * @FunctionName: removeApply
     * @Description: 删除
     * @Author: 徐一贺
     * @CreateDate: 2020/4/21 12:39
     * @Phone: 18241927380
     * @Param: [param]
     * @Return: com.zhongwang.mms.common.JsonResult
     * @Version: 1.0.0
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean removeApply(PChangeOrderModel param) {
        try {
            //获取申请列表，往回标记库存
            List<PChangeOrderModel> pChangeOrderModelList = purChangeDao.findPChangeOrderByCeoId(param.getCeoIds());
            for (int i = 0; i < pChangeOrderModelList.size(); i++) {
                if (pChangeOrderModelList.get(i).getCeoDataStatus() == null) {
                    PInventory ceoUsePInventory = purChangeDao.getInventoryPrimaryKey(pChangeOrderModelList.get(i).getCeoUseItyId());
                    ceoUsePInventory.setItyAvaNum(ceoUsePInventory.getItyAvaNum() + pChangeOrderModelList.get(i).getCeoNeedNum());
                    if (ceoUsePInventory.getItyAvaNum() <= ceoUsePInventory.getItyNum()) {
                        purPInventoryDao.updateItyAvaNumByPrimary(ceoUsePInventory);
                        pChangeOrderModelList.get(i).setCeoRemoveUserId(ShiroUtils.getUserId());
                        pChangeOrderModelList.get(i).setCeoRemoveDate(getDateTimeService.getSysDateTime());
                        purChangeDao.deletePChangeOrderModelByPrimaryKey(pChangeOrderModelList.get(i));
                        logService.saveLog("【外购件】删除串料申请", "");
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return false;
        }
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    /**
     *@FunctionName: reject
     *@Description: 驳回
     *@Author: 徐一贺
     *@CreateDate: 2020/4/21 12:39
     *@Phone: 18241927380
     *@Param: [param]
     *@Return: com.zhongwang.mms.common.JsonResult
     *@Version: 1.0.0
     */
    public JsonResult reject(PChangeOrderModel param) {
        JsonResult jsonResult = new JsonResult();
        List<String> errorList = new ArrayList<String>();
        try {
            //获取申请列表，往回标记库存
            List<PChangeOrderModel> pChangeOrderModelList = purChangeDao.findPChangeOrderByCeoId(param.getCeoIds());
            for (int i = 0; i < pChangeOrderModelList.size(); i++) {
                if (pChangeOrderModelList.get(i).getCeoAppyStatus() == 2) {
                    PChangeOrderModel changeOrderSetCeoApplyStatusModel = new PChangeOrderModel();
                    changeOrderSetCeoApplyStatusModel.setCeoIds(pChangeOrderModelList.get(i).getCeoId().toString());
                    changeOrderSetCeoApplyStatusModel.setCeoAppyStatus(4);
                    purChangeDao.updatePChangeOrderCeoAppyStatusByCeoId(changeOrderSetCeoApplyStatusModel);
                    logService.saveLog("【外购件】驳回串料申请", "驳回的串料申请编码：" + pChangeOrderModelList.get(i).getCeoCode());
                } else {
                    errorList.add("单据编号为：" + pChangeOrderModelList.get(i).getCeoCode() + "的串料申请已驳回或已经执行！<br>");
                }
            }
//            param.setCeoAppyStatus(4);
//            purChangeDao.updatePChangeOrderCeoAppyStatusByCeoId(param);
            if (errorList.size() > 0) {
                jsonResult.setType(JsonResult.ResultType.ERROR);
                jsonResult.setMsg(errorList.toString());
                return jsonResult;
            } else {
                jsonResult.setType(JsonResult.ResultType.SUCCESS);
                jsonResult.setMsg("驳回成功！");
                return jsonResult;
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            jsonResult.setType(JsonResult.ResultType.ERROR);
            jsonResult.setMsg("驳回失败！");
            return jsonResult;
        }
    }

    /**
     * @FunctionName: inventoryList
     * @Description: 获取项目在库库存列表
     * @Author: 徐一贺
     * @CreateDate: 2020/4/23 9:15
     * @Phone: 18241927380
     * @Param: [param] 查询参数
     * @Return: com.zhongwang.mms.common.JsonResult
     * @Version: 1.0.0
     */
    public List<PInventoryModel> findInventoryList(PInventoryModel param) {
        List<PInventoryModel> list = null;
        try {
            param.setSort(StringUtils.convertFieldToColumn(param.getSort()));
            param.setItyStockType(2);
            list = purPInventoryDao.findInventoryListForChange(param);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

    /**
     * @FunctionName: getChangeModel
     * @Description: 根据主键获取串料申请单数据
     * @Author: 徐一贺
     * @CreateDate: 2020/4/24 13:39
     * @Phone: 18241927380
     * @Param: [ceoId] 主键
     * @Return: [ChangeModel] 串料申请单
     * @Version: 1.0.0
     */
    public ChangeModel getChangeModel(String ceoId) {
        return purChangeDao.getPChangeOrderByCeoId(ceoId);
    }

    @Value("${spring.profiles.active}")
    private String active;

    /**
     * @FunctionName: exportPurInvExcel
     * @Description: 导出所有串料模板
     * @DesignIdea:
     * @Author: 徐一贺
     * @CreateDate: 2020/6/13 15:49
     * @Phone: 18241927380
     * @Param: [response, param]
     * @Return: void
     * @Throw:
     * @Version: v1.0.0
     */
    public JsonResult exportPurInvExcel(PurInvQueryModel param) {
        JsonResult jsonResult = new JsonResult();
        //获取当前用户
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        logService.saveLog("外购件串料记录——导出", "用户:【" + user.getName() + "】执行导出操作！");
        //存储/读取Excel的文件夹的路径 mms文件夹下/用户账户/
        String path = uploadPath + user.getAccount() + "/";
        String excelFileName = "外购件串料和库存划项目模板列表.xlsx";
        try {
            //1.创建临时内存表名
            String tempTableName = "##" + user.getAccount() + (UUID.randomUUID().toString().replace("-", ""));
            param.setTempTableName(tempTableName);
            //2.查询出数据导入到临时表
            purChangeDao.createPinventoryTempTable(param);
            //3.导出Excel
            if (ExportExcelUtils.BuildExcel(path, excelFileName, tempTableName, active, false)) {
                jsonResult.setData(excelFileName);
                jsonResult.setType(JsonResult.ResultType.SUCCESS);
            } else {
                jsonResult.setType(JsonResult.ResultType.ERROR);
            }
        } catch (Exception e) {
            log.debug(e.getMessage());
            e.printStackTrace();
            jsonResult.setType(JsonResult.ResultType.ERROR);
        }
        return jsonResult;
    }


    /**
     * @FunctionName: errorExport
     * @Description: 导出15天内错误的串料/库存划项目标记信息
     * @DesignIdea: 导出15天内错误的串料/库存划项目标记信息
     * @Author: 徐一贺
     * @CreateDate: 2020/6/16 9:18
     * @Phone: 18241927380
     * @Param: [userId] 申请者主键
     * @Return:
     * @Throw:
     * @Version: v 1.0.0
     */
    public void errorExport(HttpServletResponse response, Integer userId) {
//        List<PChangeImportExportLogModel> list = purChangeDao.findPChangeImportExportLogModellListSelective(userId);
//        User user = (User) SecurityUtils.getSubject().getPrincipal();
//        String path = uploadPath + user.getAccount() + "/";
//        FileUtils.export(path, "外购件批量串料错误列表.xls", PChangeImportExportLogModel.class, "sheet1", list, response);


        PChangeImportExportLogModel param = new PChangeImportExportLogModel();
        param.setUserId(userId);
        List<PChangeImportExportLogModel> list = new ArrayList<>();
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        String path = uploadPath + user.getAccount() + "/";
        Subject userSubject = ShiroUtils.getSubject();
        //1.创建临时内存表名
        String tempTableName = "##" + ShiroUtils.getUser().getAccount() + (UUID.randomUUID().toString().replace("-", ""));
        param.setTempTableName(tempTableName);
        //2.查询出数据导入到临时表
        purChangeDao.createErrorLogTempTable(param);
        //3.查询临时内存表数据导出
        Integer dataCount = purChangeDao.getErrorLogTempTableDataCount(param);
        int step = 5000;
        FileUtils.mkdirs(path);
        // 方法1 如果写到同一个sheet
        path = path + "外购件批量串料错误列表.xls";
        ExcelWriter excelWriter = null;
        // 这里注意 如果同一个sheet只要创建一次
        Integer sheetDataCount = 60000;
        WriteSheet writeSheet = EasyExcel.writerSheet("错误记录0-" + sheetDataCount).build();
        try {
            // 这里 需要指定写用哪个class去写
            excelWriter = EasyExcel.write(path, PChangeImportExportLogModel.class).build();
            for (int topCount = 5000, notHaveTopCount = 0; notHaveTopCount < dataCount; notHaveTopCount += step) {
                param.setTopCount(topCount);
                param.setNotHaveTopCount(notHaveTopCount);
                if (notHaveTopCount % sheetDataCount == 0) {
                    writeSheet = EasyExcel.writerSheet("错误记录" + notHaveTopCount + "-" + (notHaveTopCount + sheetDataCount)).build();
                }
                list = purChangeDao.selectErrorLogTempTableByParam(param);
                if (list != null) {
                    excelWriter.write(list, writeSheet);
                }
            }
            if (dataCount == 0) {
                param.setTopCount(1000);
                param.setNotHaveTopCount(0);
                list = purChangeDao.selectErrorLogTempTableByParam(param);
                excelWriter.write(list, writeSheet);
            }
            //4.删除临时内存表
            purChangeDao.dropErrorLogTempTable(tempTableName);
        } finally {
            // 千万别忘记finish 会帮忙关闭流
            if (excelWriter != null) {
                excelWriter.finish();
            }
        }
        //5.下载
        FileUtils.downloadFile(path, response);
    }

    public JsonResult importExcel(MultipartFile file) {
        JsonResult result = new JsonResult();
        List<TProjectModel> TProjectModels = tProjectDao.getTProjects();
        try {
            FileUtils.importExcel(file, PChangeOrderExcelModel.class, new PChangeOrderListener(purChangeDao, boardDao, new ImportCallBack() {
                @Override
                public void onSuccess() {
                    result.setType(JsonResult.ResultType.SUCCESS);
                    result.setMsg("批量导入成功！");
                }

                @Override
                public void onWarning(List list) {
                    result.setType(JsonResult.ResultType.ERROR);
                    for (int i = 0; i < list.size(); i++) {
                        purChangeDao.insertErrorLog((PChangeImportExportLogModel) list.get(i));
                    }
                }
            }, logService, baseService, purPInventoryDao, tWarehouseInfoDao, tProjectDao, boardService,TProjectModels));
        } catch (IOException e) {
            e.printStackTrace();
            log.error(e.getMessage());
            result.setType(JsonResult.ResultType.ERROR);
            result.setMsg("批量导入失败！");
        }
        return result;
    }

    public List<TWarehouseInfo> findWarehouseInfoList() {
        return purWarInManageDao.findWarehouseInfoList();
    }
}